summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_hardware_timer.h
blob: 00bef6ea157b0fe85d6062e101dfd95a46c30a2b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include "core/hle/kernel/k_hardware_timer_base.h"

namespace Core::Timing {
struct EventType;
} // namespace Core::Timing

namespace Kernel {

class KHardwareTimer : /* public KInterruptTask, */ public KHardwareTimerBase {
public:
    explicit KHardwareTimer(KernelCore& kernel) : KHardwareTimerBase{kernel} {}

    // Public API.
    void Initialize();
    void Finalize();

    s64 GetCount() const {
        return GetTick();
    }

    void RegisterTask(KTimerTask* task, s64 time_from_now) {
        this->RegisterAbsoluteTask(task, GetTick() + time_from_now);
    }

    void RegisterAbsoluteTask(KTimerTask* task, s64 task_time) {
        KScopedDisableDispatch dd{m_kernel};
        KScopedSpinLock lk{this->GetLock()};

        if (this->RegisterAbsoluteTaskImpl(task, task_time)) {
            if (task_time <= m_wakeup_time) {
                this->EnableInterrupt(task_time);
            }
        }
    }

private:
    void EnableInterrupt(s64 wakeup_time);
    void DisableInterrupt();
    bool GetInterruptEnabled();
    s64 GetTick() const;
    void DoTask();

private:
    // Absolute time in nanoseconds
    s64 m_wakeup_time{std::numeric_limits<s64>::max()};
    std::shared_ptr<Core::Timing::EventType> m_event_type{};
};

} // namespace Kernel